﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace Fast
{
    /// <summary>
    /// 启动类选项
    /// </summary>
    [SkipScan]
    public class FastStartupOptions
    {
        /// <summary>
        /// 启动类集合
        /// </summary>
        internal ICollection<IFastStartup> FastStartups { get; } = new List<IFastStartup>();
        /// <summary>
        /// 发现启动类
        /// </summary>
        internal void DiscoverFastStartup() => DiscoverFastStartup(App.Assemblies.ToArray());
        /// <summary>
        /// 发现启动类
        /// </summary>
        /// <param name="assemblies"></param>
        internal void DiscoverFastStartup(params Assembly[] assemblies)
        {
            if (assemblies == null || assemblies.Length == 0 || assemblies.All(a => a == null))
            {
                throw new ArgumentNullException(nameof(assemblies), "没有从指定的程序集发现启动类");
            }
            foreach (var type in assemblies.SelectMany(a => a.ExportedTypes).Where(t => t.IsClass && !t.IsAbstract && !t.IsGenericType))
            {
                if (typeof(IFastStartup).IsAssignableFrom(type))
                {
                    var instance = CreateInstance<IFastStartup>(type);
                    FastStartups.Add(instance);
                }
            }
        }
        /// <summary>
        /// 创建实现实例
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        private TResult CreateInstance<TResult>(Type type)
        {
            try
            {
                return (TResult)Activator.CreateInstance(type);
            }
            catch (System.Exception ex)
            {
                throw new InvalidOperationException($"未能为{nameof(TResult)}创建类型为{type.Name}的实例", ex);
            }
        }
    }
}
